FlatKitFog.shader 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. Shader "Hidden/FlatKit/FogFilter"
  2. {
  3. Properties
  4. {
  5. [Toggle(USE_DISTANCE_FOG)]_UseDistanceFog ("Use Distance", Float) = 0
  6. [Toggle(USE_DISTANCE_FOG_ON_SKY)]_UseDistanceFogOnSky ("Use Distance Fog On Sky", Float) = 0
  7. [Space]
  8. _Near ("Near", Float) = 0
  9. _Far ("Far", Float) = 100
  10. [Space]
  11. _DistanceFogIntensity ("Distance Fog Intensity", Range(0, 1)) = 1
  12. [Space(25)]
  13. [Toggle(USE_HEGHT_FOG)]_UseHeightFog ("Use Height", Float) = 0
  14. [Toggle(USE_HEGHT_FOG_ON_SKY)]_UseHeightFogOnSky ("Use Height Fog On Sky", Float) = 0
  15. [Space]
  16. _LowWorldY ("Low", Float) = 0
  17. _HighWorldY ("High", Float) = 10
  18. [Space]
  19. _HeightFogIntensity ("Height Fog Intensity", Range(0, 1)) = 1
  20. [Space(25)]
  21. _DistanceHeightBlend ("Distance / Height blend", Range(0, 1)) = 0.5
  22. }
  23. SubShader
  24. {
  25. Tags
  26. {
  27. "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"
  28. }
  29. LOD 100
  30. ZWrite Off Cull Off
  31. Pass
  32. {
  33. Name "Fog"
  34. HLSLPROGRAM
  35. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
  36. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
  37. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
  38. #pragma multi_compile _ _USE_DRAW_PROCEDURAL
  39. sampler2D _DistanceLUT;
  40. float _Near;
  41. float _Far;
  42. half _UseDistanceFog;
  43. half _UseDistanceFogOnSky;
  44. sampler2D _HeightLUT;
  45. float _LowWorldY;
  46. float _HighWorldY;
  47. half _UseHeightFog;
  48. half _UseHeightFogOnSky;
  49. float _DistanceFogIntensity;
  50. float _HeightFogIntensity;
  51. float _DistanceHeightBlend;
  52. #define ALMOST_ONE 0.999
  53. // Using `_CameraColorTexture` instead of the opaque texture `SampleSceneColor` to handle transparency.
  54. TEXTURE2D_X(_CameraColorTexture);
  55. SAMPLER(sampler_CameraColorTexture);
  56. float4 _CameraColorTexture_TexelSize;
  57. // Z buffer depth to linear 0-1 depth
  58. // Handles orthographic projection correctly
  59. float Linear01Depth(float z)
  60. {
  61. float isOrtho = unity_OrthoParams.w;
  62. float isPers = 1.0 - unity_OrthoParams.w;
  63. z *= _ZBufferParams.x;
  64. return (1.0 - isOrtho * z) / (isPers * z + _ZBufferParams.y);
  65. }
  66. float4 SampleCameraColor(float2 uv)
  67. {
  68. return SAMPLE_TEXTURE2D_X(_CameraColorTexture, sampler_CameraColorTexture, UnityStereoTransformScreenSpaceTex(uv));
  69. }
  70. float LinearEyeDepth(float z)
  71. {
  72. return rcp(_ZBufferParams.z * z + _ZBufferParams.w);
  73. }
  74. float4 Fog(float2 uv, float3 screen_pos)
  75. {
  76. float4 original = SampleCameraColor(uv);
  77. const float depthPacked = SampleSceneDepth(uv);
  78. const float depthEye = LinearEyeDepth(depthPacked);
  79. const float depthCameraPlanes = Linear01Depth(depthPacked);
  80. const float depthAbsolute = _ProjectionParams.y + (_ProjectionParams.z - _ProjectionParams.y) *
  81. depthCameraPlanes;
  82. const float depthFogPlanes = saturate((depthAbsolute - _Near) / (_Far - _Near));
  83. const float isSky = step(ALMOST_ONE, depthCameraPlanes);
  84. float4 distanceFog = tex2D(_DistanceLUT, float2(depthFogPlanes, 0.5));
  85. distanceFog.a *= step(isSky, _UseDistanceFogOnSky);
  86. distanceFog.a *= _UseDistanceFog * _DistanceFogIntensity;
  87. const float3 worldPos = screen_pos * depthEye + _WorldSpaceCameraPos;
  88. const float heightUV = saturate((worldPos.y - _LowWorldY) / (_HighWorldY - _LowWorldY));
  89. float4 heightFog = tex2D(_HeightLUT, float2(heightUV, 0.5));
  90. heightFog.a *= step(isSky, _UseHeightFogOnSky);
  91. heightFog.a *= _UseHeightFog * _HeightFogIntensity;
  92. float fogBlend = _DistanceHeightBlend;
  93. if (!_UseDistanceFog) fogBlend = 1.0;
  94. if (!_UseHeightFog) fogBlend = 0.0;
  95. const float4 fog = lerp(distanceFog, heightFog, fogBlend);
  96. float4 final = lerp(original, fog, fog.a);
  97. final.a = original.a;
  98. return final;
  99. }
  100. struct Attributes
  101. {
  102. float4 positionOS: POSITION;
  103. float2 uv: TEXCOORD0;
  104. UNITY_VERTEX_INPUT_INSTANCE_ID
  105. };
  106. struct Varyings
  107. {
  108. float2 uv: TEXCOORD0;
  109. float3 screen_pos: TEXCOORD1;
  110. float4 vertex: SV_POSITION;
  111. UNITY_VERTEX_OUTPUT_STEREO
  112. };
  113. Varyings vert(Attributes input)
  114. {
  115. Varyings output = (Varyings)0;
  116. UNITY_SETUP_INSTANCE_ID(input);
  117. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  118. #if _USE_DRAW_PROCEDURAL
  119. output.vertex = float4(input.positionOS.xyz, 1.0);
  120. #if UNITY_UV_STARTS_AT_TOP
  121. output.vertex.y *= -1;
  122. #endif
  123. #else
  124. const VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
  125. output.vertex = vertexInput.positionCS;
  126. #endif
  127. output.uv = input.uv;
  128. output.screen_pos = ComputeScreenPos(output.vertex).xyz;
  129. return output;
  130. }
  131. half4 frag(Varyings input): SV_Target
  132. {
  133. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  134. float4 c = Fog(input.uv, input.screen_pos);
  135. return c;
  136. }
  137. #pragma vertex vert
  138. #pragma fragment frag
  139. ENDHLSL
  140. }
  141. }
  142. FallBack "Diffuse"
  143. }